<template>
	<el-dialog v-model="visible" title="批量建表" :close-on-click-modal="false" :width="850">
		<div v-loading="loading">
			<el-steps :active="active" style="width: 100%" align-center>
				<el-step title="选择建表对象"> </el-step>
				<el-step title="选择目标库"> </el-step>
				<el-step title="建表确认" />
			</el-steps>
			<br />
			<div v-if="active == 0">
				<div class="addTableTransfer" style="text-align: center; position: relative">
					<el-transfer
						ref="transfer"
						v-model="addTableData"
						filterable
						:props="{
							key: 'id',
							label: 'code'
						}"
						:titles="['源列表', '目的表']"
						:data="tableData"
						:filter-method="filterMethod"
						filter-placeholder="请输入搜索内容"
						class="custom-transfer"
					>
						<!-- :filter-method="filterMethod"
						filter-placeholder="请输入搜索内容" -->
						<template #default="{ option }">
							<span :title="option.label">{{ option.code }}</span>
						</template>
						<!-- <template #left-footer>
							<el-input clearable v-model="searchText" placeholder="请输入搜索内容" @input="handleSearch" />
						</template> -->
					</el-transfer>

					<div style="position: absolute; top: 10px; left: 330px; cursor: pointer">
						<el-popover placement="bottom" title="" :width="200" trigger="click">
							<template #reference>
								<el-icon size="20"><InfoFilled /></el-icon>
							</template>
							当前只展示200条数据，如需查看其他数据，请输入详细内容搜索
						</el-popover>
					</div>
				</div>
			</div>
			<div v-else-if="active == 1" style="min-height: 400px; display: flex; justify-content: center">
				<div style="margin-top: 50px">
					选择目标库:
					<el-select placeholder="选择目标库" filterable v-model="sqlId" @change="sqlChange">
						<el-option v-for="item in sqlList" :label="item.name" :value="item.id"></el-option>
					</el-select>
				</div>
			</div>
			<div v-else-if="active == 2" style="min-height: 400px">
				<el-row>
					<el-col :span="6">
						<div style="text-align: center">选择目标数据库</div>
					</el-col>
					<el-col :span="6">
						<div style="text-align: center">选择schema</div>
					</el-col>
					<el-col :span="6">
						<div style="text-align: center">选择对象表</div>
					</el-col>
					<el-col :span="6">
						<div style="text-align: center">表重命名</div>
					</el-col>
				</el-row>
				<template v-if="saveTableData.length">
					<el-scrollbar height="400px">
						<el-row :gutter="16" style="margin: 10px" v-for="(tabData, index) in saveTableData">
							<el-col :span="6">
								<el-input disabled v-model="sqlName"></el-input>
								<!-- <el-select v-model="sqlId" placeholder="选择目标数据库" filterable disabled style="width: 100%">
									<el-option v-for="item in sqlList" :label="item.name" :value="item.id"></el-option>
								</el-select> -->
							</el-col>
							<el-col :span="6">
								<el-input disabled v-model="tabData.targetSchema"></el-input>
							</el-col>
							<el-col :span="6">
								<el-input v-model="tabData.metaTableName" disabled></el-input>
								<!-- <el-select :model-value="tabData.id" placeholder="选择对象表" filterable disabled style="width: 100%">
									<el-option v-for="ele in sqlTableList" :key="ele.id" :label="ele.code" :value="ele.id"></el-option>
								</el-select> -->
							</el-col>
							<el-col :span="6">
								<el-input v-model="tabData.targetTableName"></el-input>
							</el-col>
						</el-row>
					</el-scrollbar>
				</template>
				<template v-else>
					<el-empty></el-empty>
				</template>
			</div>
		</div>
		<template #footer>
			<div class="dialog-footer">
				<el-button @click="visible = false">取消</el-button>
				<el-button v-if="active != 0" @click="preStep"> 上一步 </el-button>
				<el-button v-if="active != 2" type="primary" @click="nextStep"> 下一步 </el-button>
				<el-button v-if="active == 2" type="primary" @click="complateHandle"> 完成 </el-button>
			</div>
		</template>
	</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { listDatabase } from '@/api/data-integrate/database'
import { getMetadataSyncList, listChildApi, createMateTable } from '@/api/data-governance/metadata'
import { ElMessage } from 'element-plus'
import { debounce } from '@/utils/tool'

const emit = defineEmits(['close'])
const visible = ref(false)

const sqlList = ref([])
const sqlId = ref()
const sqlSelData = ref()
const sqlName = ref()
const active = ref(0)

const transfer = ref()

const allData = ref([])
const tableData = ref([])
const addTableData = ref([])
const saveTableData = ref([])

const searchText = ref()

const databaseSchema = ref()

const sqlTableList = ref([])

const metaProData = ref() // 库 属性信息
const loading = ref(false)

const filterKey = ref('')
const searchKey = ref('')
const notTimeOut = ref([])
const timeOut = ref()

const handleSearch = debounce(
	() => {
		getLeftData()
	},
	500,
	''
)

const filterMethod = (key, item) => {
	if (key) {
		if (!addTableData.value.find(it => it == item.id)) {
			// filterKey判断当前搜索的值是否有变化
			if (filterKey.value !== key) {
				notTimeOut.value = []
				filterKey.value = key
			}
			if (item.code.indexOf(key) > -1) {
				notTimeOut.value.push(true)
				return true
			} else {
				notTimeOut.value.push(false)
			}
			// notTimeOut记录循环是否结束，防止多次请求远程
			// 若notTimeOut中没有true值，则表示搜索的数据不在源数据中，则要请求远程
			if (notTimeOut.value.length + addTableData.value.length === allData.value.length && !notTimeOut.value.find(item => item === true)) {
				// 若进来，则清空notTimeOut，防止再次请求远程
				notTimeOut.value = []
				clearTimeout(timeOut.value)
				timeOut.value = setTimeout(() => {
					// searchKey判断是否已经请求过远程，因filterMethod方法是计算属性，会使请求重复，则需要searchKey判断
					if (searchKey.value !== key) {
						searchText.value = key
						getLeftData()
					}
				}, 1000)
			}
		} else {
			if (item.code.indexOf(key) > -1) {
				return true
			}
		}
	} else {
		return true
	}
}

const sqlChange = value => {
	sqlSelData.value = sqlList.value.filter(item => item.id == value) ? sqlList.value.filter(item => item.id == value)[0] : ''

	sqlName.value = sqlSelData.value ? sqlSelData.value.name : ''
	// databaseSchema.value = sqlList.value.filter(item => item.id == value)[0].databaseSchema
}

const nodeData = ref({})
const init = (data, metaProperties) => {
	loading.value = false
	sqlList.value = []
	visible.value = true
	nodeData.value = data
	sqlTableList.value = []
	sqlId.value = ''
	saveTableData.value = []
	databaseSchema.value = ''
	sqlSelData.value = ''
	sqlName.value = ''

	notTimeOut.value = []
	filterKey.value = ''
	searchKey.value = ''
	searchText.value = ''

	allData.value = []
	tableData.value = []
	addTableData.value = []

	metaProData.value = metaProperties

	listChildApi(nodeData.value.id).then(res => {
		sqlTableList.value = res.data
	})

	if (transfer.value) {
		transfer.value.clearQuery('left')
		transfer.value.clearQuery('right')
	}

	nextTick(() => {
		getLeftData()
		getSqData()

		active.value = 0
	})
}

const getLeftData = () => {
	searchKey.value = searchText.value
	getMetadataSyncList({
		tableCreateStatus: 'success',
		parentId: nodeData.value.id,
		code: searchText.value
	}).then(res => {
		res.data.forEach(item => {
			if (!allData.value.find(it => it.id === item.id)) {
				allData.value.push(item)
			}
		})

		tableData.value = JSON.parse(JSON.stringify(allData.value))
	})
}

const getSqData = () => {
	listDatabase().then(res => {
		sqlList.value = res.data.filter(item => item.databaseName == 'postgres')
	})
}

const preStep = () => {
	active.value--
}

const nextStep = () => {
	active.value++

	if (active.value == 2) {
		saveTableData.value = []
		let metaJdbcUrl = ''
		let metaUserName = ''
		let metaPassword = ''
		let metaSchema = ''
		let databaseType = ''
		if (addTableData.value.length) {
			;(metaJdbcUrl = metaProData.value.length ? metaProData.value.filter(ele => ele.code == 'jdbcUrl')[0].value : ''),
				(metaUserName = metaProData.value.length ? metaProData.value.filter(ele => ele.code == 'username')[0].value : '')
			metaPassword = metaProData.value.length ? metaProData.value.filter(ele => ele.code == 'password')[0].value : ''
			metaSchema = metaProData.value.length ? metaProData.value.filter(ele => ele.code == 'databaseName')[0].value : ''
			databaseType = metaProData.value.length ? metaProData.value.filter(ele => ele.code == 'databaseType')[0].value : ''
		}
		addTableData.value.forEach(item => {
			const tableName = sqlTableList.value.filter(ele => ele.id == item)[0].code
			const label = sqlTableList.value.filter(ele => ele.id == item)[0].label
			saveTableData.value.push({
				databaseType: databaseType,
				id: item,
				dataSourceName: nodeData.value.code,
				targetId: sqlId.value,
				metaJdbcUrl: metaJdbcUrl,
				metaUserName: metaUserName,
				metaPassword: metaPassword,
				metaSchema: metaSchema,
				metaTableName: tableName,
				metaTableRemarks: label,
				targetJdbcUrl: sqlSelData.value ? sqlSelData.value.jdbcUrl : '',
				targetUserName: sqlSelData.value ? sqlSelData.value.userName : '',
				targetPassword: sqlSelData.value ? sqlSelData.value.password : '',
				targetSchema: sqlSelData.value ? sqlSelData.value.databaseSchema : '',
				targetTableName: tableName
			})
		})
	}
}
const complateHandle = () => {
	if (!addTableData.value.length) {
		ElMessage.error('请选择需要创建的表')
		return
	}

	if (!sqlId.value) {
		ElMessage.error('请选择目标库')
		return
	}

	// console.log(saveTableData.value)
	// console.log(JSON.stringify(saveTableData.value))

	const tableNameNoData = saveTableData.value.filter(item => !item.targetTableName)
	if (tableNameNoData.length) {
		ElMessage.error('表名称不能为空')
		return
	}

	if (saveTableData.value.length > 1) {
		const tableNameSomeData = saveTableData.value.filter((item, index, self) => {
			return self.findIndex(t => t.targetTableName === item.targetTableName) != index
		})
		if (tableNameSomeData.length) {
			ElMessage.error('表名称不能重复')
			return
		}
	}
	
	loading.value = true
	createMateTable(saveTableData.value)
		.then(res => {
			ElMessage.success('创建成功')
			visible.value = false
			loading.value = false
			emit('close')
		})
		.catch(() => {
			loading.value = false
		})
}

defineExpose({
	init
})
</script>
<style lang="scss" scoped></style>
